// MaskVolume.cpp: implementation of the RxMaskVolume class.
//
//////////////////////////////////////////////////////////////////////


#include "MaskVolume.h"
#include <xmmintrin.h>

#include <iostream>

// #ifdef _DEBUG
// #undef THIS_FILE
// static char THIS_FILE[]=__FILE__;
// #define new DEBUG_NEW
// #endif


#define	CACHESIZE	32

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

RxMaskVolume::RxMaskVolume()
{
	m_pbyMask = NULL;

	m_iMaskSize = 0;
	m_iVolX = m_iVolY = m_iVolZ = 0;
}

RxMaskVolume::~RxMaskVolume()
{
	if (m_pbyMask) {
        delete [] m_pbyMask;
        
		//::VirtualFree(m_pbyMask, m_iMaskSize, MEM_DECOMMIT);
		//::VirtualFree(m_pbyMask, 0, MEM_RELEASE);
	}
}


bool RxMaskVolume::CreateMaskVolume(int iVolX, int iVolY, int iVolZ, char chFill ) // = 0
{
	if (m_pbyMask) {
        delete [] m_pbyMask;
		//::VirtualFree(m_pbyMask, m_iMaskSize, MEM_DECOMMIT);
		//::VirtualFree(m_pbyMask, 0, MEM_RELEASE);

		m_pbyMask = NULL;
	}

//	if (m_pbyMask)
//		return FALSE;

	m_iVolX = iVolX;
	m_iVolY = iVolY;
	m_iVolZ = iVolZ;

	m_iMaskSize = iVolX * iVolY * iVolZ / 8;
	m_pbyMask = (unsigned char*)(new char[m_iMaskSize]);
    //m_pbyMask = (unsigned char*)::VirtualAlloc(NULL, m_iMaskSize, MEM_RESERVE | MEM_TOP_DOWN, PAGE_READWRITE);
	if (!m_pbyMask) {		// can't reserve memory
		m_iMaskSize = 0;
		return false;
	}
	//m_pbyMask = (unsigned char*)::VirtualAlloc(m_pbyMask, m_iMaskSize, MEM_COMMIT, PAGE_READWRITE);
	memset(m_pbyMask, chFill, sizeof(unsigned char) * m_iMaskSize);

	return true;
}

bool RxMaskVolume::CreateNULLMask(int iVolX, int iVolY, int iVolZ)
{
	if (m_pbyMask)
		return false;

	m_iVolX = iVolX;
	m_iVolY = iVolY;
	m_iVolZ = iVolZ;

	m_iMaskSize = iVolX * iVolY * iVolZ / 8;

	return true;
}

void RxMaskVolume::DestroyMaskVolume()
{
	if (m_pbyMask) {
        delete [] m_pbyMask;
		//::VirtualFree(m_pbyMask, m_iMaskSize, MEM_DECOMMIT);
		//::VirtualFree(m_pbyMask, 0, MEM_RELEASE);

		m_pbyMask = NULL;
	}
}

RxMaskVolume RxMaskVolume::operator =(const RxMaskVolume &maskSrc)
{
	if(m_iMaskSize != maskSrc.m_iMaskSize)
	{
		std::cout << "m_iMaskSize != maskSrc.m_iMaskSize" << std::endl;
		exit(-1);
	}

	memcpy(m_pbyMask, maskSrc.m_pbyMask, m_iMaskSize);

	return *this;
}

void RxMaskVolume::operator |= (const RxMaskVolume &maskSrc)
{
	if(m_iMaskSize != maskSrc.m_iMaskSize)
	{
		std::cout << "m_iMaskSize != maskSrc.m_iMaskSize" << std::endl;
		exit(-1);
	}

	if(m_iMaskSize %4 != 0)
	{
		std::cout << "m_iMaskSize %4 != 0" << std::endl;
		exit(-1);
	}

	unsigned int* pSrc = (unsigned int* )maskSrc.m_pbyMask;
    unsigned int* pDst = (unsigned int* )m_pbyMask;

	int iLoopCount = m_iMaskSize/4;
	for(int i=0; i<iLoopCount; i++) {
		pDst[i] |= pSrc[i];

	}
}

void RxMaskVolume::AssignMaskVolume(unsigned char* pbyNewMaskVol)
{
	DestroyMaskVolume();

	m_pbyMask = pbyNewMaskVol;
}

bool RxMaskVolume::CopyMaskVolume(const RxMaskVolume* pmvSrc)
{
	if (m_iVolX != pmvSrc->m_iVolX || m_iVolY != pmvSrc->m_iVolY || m_iVolZ != pmvSrc->m_iVolZ)
		return false;

    memcpy(m_pbyMask, pmvSrc->m_pbyMask, m_iMaskSize);
	//::CopyMemory(m_pbyMask, pmvSrc->m_pbyMask, m_iMaskSize);

	return true;
}
